package view;

import java.awt.Dimension;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;


/**
 * Factory class for View objects that also contains int constants for each View
 * type
 * 
 * @author Zachary Hopping
 * edited by Grant Oakley
 * 
 */
public final class Factory {
    /**
     * Constant to plot a 2D line graph.
     */
    public static final int LINE_GRAPH = 0;
    /**
     * Constant to plot a 2D histogram.
     */
    public static final int HISTOGRAM = 1;

    private static final Map<String, Integer> VISUALIZATION_TYPES = new HashMap<String, Integer>();
    static {
        VISUALIZATION_TYPES.put("Line Graph", LINE_GRAPH);
        VISUALIZATION_TYPES.put("Histogram", HISTOGRAM);
    }

    private static final String UNRECOGNIZED_VIEW_TYPE_ERROR_MESSAGE = "Unsupported view type";

    /**
     * empty constructor
     */
    protected Factory() { }
    /**
     * Gets a list of the visualaization types that can be built with Factory.
     * 
     * @return an array of strings, where each element is a visualization type
     */
    public static String[] getAvailableVisualizations () {
        /*conversion must be made in the below manner because we need to assign list indices
         * to each element in the keySet, and we cannot iterate through the set with a "for each" loop
         */
        Set<String> visualizationKeySet = VISUALIZATION_TYPES.keySet();
        Object[] visualizationsAsObjects = visualizationKeySet.toArray();
        String[] visualizationsAsStrings = new String[visualizationsAsObjects.length];
        for (int i = 0; i < visualizationsAsObjects.length; i++) {
            visualizationsAsStrings[i] = visualizationsAsObjects[i].toString();
        }
        return visualizationsAsStrings;
    }

    /**
     * Creates an instance of a visualization of the specified type.
     * 
     * @param viewType constant identifying the type of view to be returned
     * @return a new View object of the type indicated by the VIEW_TYPE
     *         parameter
     */
    public static Visualization makeView (int viewType) {
        switch (viewType) {
            case LINE_GRAPH:
                return new LineGraph();
            case HISTOGRAM:
                return new Histogram();
            default:
                throw new ViewException(UNRECOGNIZED_VIEW_TYPE_ERROR_MESSAGE, viewType);
        }
    }

    /**
     * Creates an instance of a visualization of the specified type with a
     * specified size.
     * 
     * @param viewType constant identifying the type of view to be returned
     * @param size sets the size of our visualization
     * @return a new View object of the type indicated by the VIEW_TYPE
     *         parameter
     */
    public static Visualization makeView (int viewType, Dimension size) {
        switch (viewType) {
            case LINE_GRAPH:
                return new LineGraph(size);
            case HISTOGRAM:
                return new Histogram(size);
            default:
                throw new ViewException(UNRECOGNIZED_VIEW_TYPE_ERROR_MESSAGE, viewType);
        }
    }

    /**
     * Creates an instance of visualization of the type specified using a
     * String. The list of available strings can be found using
     * getAvailableVisualizations().
     * 
     * @param viewType a string specifying the view type
     * @return a View object of the specified type
     */
    public static Visualization makeView (String viewType) {
        if (VISUALIZATION_TYPES.containsKey(viewType)) {
            return makeView(VISUALIZATION_TYPES.get(viewType));
        }
        else {
            throw new ViewException(UNRECOGNIZED_VIEW_TYPE_ERROR_MESSAGE, viewType);
        }
    }

    /**
     * Creates an instance of visualization of the type specified using a
     * String. The list of available strings can be found using
     * getAvailableVisualizations().
     * 
     * @param viewType a string specifying the view type
     * @param size the size of the view to be returned
     * @return a View object of the specified type
     */
    public static Visualization makeView (String viewType, Dimension size) {
        if (VISUALIZATION_TYPES.containsKey(viewType)) {
            return makeView(VISUALIZATION_TYPES.get(viewType), size);
        }
        else {
            throw new ViewException(UNRECOGNIZED_VIEW_TYPE_ERROR_MESSAGE, viewType);
        }
    }
}
